import path from 'path';

import { expect } from '@jest/globals';
import * as compressing from 'compressing';
import fse from 'fs-extra';

import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import { commonJson5Operation } from '../../plugins/common-fun';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  IsEnable,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
  SignType,
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOption, TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API10,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility,
  },
  modulesOption: {
    [ModuleTemplateType.SharedLibraryWithC]: 1,
  },
};

const testTaskOption: TestTaskOption = TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L2).sign(SignType.NoSign).ohpmInstall(IsEnable.Enable).build();

const testCaseFun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();

  // 修改工程 build-profile.json5 的 strictMode 信息
  await commonJson5Operation(path.resolve(projectRootPath, 'build-profile.json5'), async (json5) => {
    json5.app.products[0].buildOption = {
      strictMode: {
        caseSensitiveCheck: true,
        useNormalizedOHMUrl: false,
      },
    };
  });

  const result = await runHvigorAsync(
    projectRootPath,
    initExecuteCommand({
      mode: 'module',
      product: 'default',
      tasks: 'assembleHsp',
      daemon: false,
    }),
  );
  expect(result.stdout).toContain('BUILD SUCCESSFUL');

  // 修改cmakeList, 添加一个 .a 静态链接的 target
  const cmakeListFilePath = path.resolve(projectRootPath, 'shareNativeCLibrary', 'src/main/cpp/CMakeLists.txt');
  let cmakeListContent = (await fse.readFile(cmakeListFilePath)).toString();
  // 当前目标是hello.cpp  改动模板需要改动地方太多
  cmakeListContent += '\nadd_library(har111 STATIC hello.cpp)\ntarget_link_libraries(har111 PUBLIC libace_napi.z.so)\n';
  await fse.writeFile(cmakeListFilePath, cmakeListContent);

  // 增量构建
  const result1 = await runHvigorAsync(
    projectRootPath,
    initExecuteCommand({
      mode: 'module',
      product: 'default',
      tasks: 'assembleHsp',
      daemon: false,
    }),
  );
  expect(result1.stdout).toContain('BUILD SUCCESSFUL');

  // 查看har包是否生成
  const harFile = path.resolve(projectRootPath, 'shareNativeCLibrary/build/default/outputs/default/shareNativeCLibrary.har');
  expect(await fse.pathExists(harFile)).toBe(true);

  // 解压 har 包
  const dirPath = path.resolve(projectRootPath, 'shareNativeCLibrary/build/default/outputs/default');
  await compressing.tgz.uncompress(harFile, dirPath);

  const ohPackageJson5File = path.resolve(dirPath, 'package', 'oh-package.json5');
  expect(await fse.pathExists(ohPackageJson5File)).toBe(true);

  // 读取 oh-package.json5
  const ohPackageJson5Obj = await fse.readJson(ohPackageJson5File);
  const soNames: string[] = ohPackageJson5Obj.nativeComponents.map((item: any) => item.name);

  // 判断 nativeComponents 里面没有 .a 静态链接文件
  const hasDotAFiles = soNames.find((item) => item.endsWith('.a'));
  expect(hasDotAFiles).toBe(undefined);
};

TestCaseBuilder.builder()
  .caseName('DTS2024102210851')
  .description('测试hsp 打的 har 包中的 oh-package.json5 中的 nativeComponents 中是否打了 .a 文件')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(testTaskOption)
  .testFun(testCaseFun)
  .load();
